
package com.zd.wechatPlatform.common.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * md5加密，des加解密
 * 
 * @author LF
 * @date 2014-12-19 上午11:08:20
 */
public class EncryptUtil {

	private static String MD5 = "MD5";
	private static String DES = "DES";

	public static final String KEY_ALGORITHM = "AES";
	public static final String CIPER_ALGORITHM = "AES";

	/**
	 * MD5加密
	 * 
	 * @author LF
	 * @date 2014-12-19 上午11:08:59
	 * @param str
	 *            加密前
	 * @return md5加密后
	 */
	public static String str2Md5(String str) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance(MD5);
		} catch (NoSuchAlgorithmException e) {
		}
		char[] charArray = str.toCharArray();
		byte[] byteArray = new byte[charArray.length];
		for (int i = 0; i < charArray.length; i++) {
			byteArray[i] = (byte) charArray[i];
		}
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexStr = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			String temp = Integer.toHexString(md5Bytes[i] & 0xff);
			if (temp.length() < 2) {
				hexStr.append(0);
			}
			hexStr.append(temp);

		}
		return hexStr.toString();
	}

	/**
	 * 根据键值des加密
	 * 
	 * @author LF
	 * @date 2014-12-19 上午11:11:36
	 * @param str
	 *            加密前串
	 * @param key
	 *            加密键
	 * @return 加密后
	 */
	public static String str2Des(String str, String key) {
		try {
			byte[] bt = desEncrypt(str.getBytes(), key.getBytes());
			String strs = new String(Base64.encodeBase64(bt),"UTF-8");
			return strs;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据键值des解密
	 * 
	 * @author LF
	 * @date 2014-12-19 上午11:18:53
	 * @param data
	 * @param key
	 * @return
	 */
	public static String strDesEcrypt(String data, String key) {
		if (data == null)
			return null;
		byte[] buf = Base64.decodeBase64(data);
		byte[] bt;
		try {
			bt = desEcrypt(buf, key.getBytes());
			return new String(bt);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 加密
	 * 
	 * @author LF
	 * @date 2014-12-19 上午11:21:05
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static byte[] desEncrypt(byte[] data, byte[] key) throws Exception {
		// 生成一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密钥数据创建DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成加密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密钥初始化Cipher对象
		cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
		return cipher.doFinal(data);
	}

	/**
	 * 解密
	 * 
	 * @author LF
	 * @date 2014-12-19 上午11:20:59
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static byte[] desEcrypt(byte[] data, byte[] key) throws Exception {
		// 生成一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密钥数据创建DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密钥初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
		return cipher.doFinal(data);
	}

	
	/**
	 * 加密 
	 * @param strSrc 原字符串
	 * @param encName 加密方式，默认为MD5
	 * @return 加密后的字符串
	 */
	public static String Encrypt(String strSrc, String encName) {
		// parameter strSrc is a string will be encrypted,
		// parameter encName is the algorithm name will be used.
		// encName dafault to "MD5"
		MessageDigest md = null;
		String strDes = null;
		
		byte[] bt = strSrc.getBytes();
		try {
			if (encName == null || encName.equals("")) {
				encName = "MD5";
			}
			md = MessageDigest.getInstance(encName);
			md.update(bt);
			strDes = bytes2Hex(md.digest()); // to HexString
		} catch (NoSuchAlgorithmException e) {
			System.out.println("Invalid algorithm.");
			return null;
		}
		return strDes;
	}

	private static String bytes2Hex(byte[] bts) {
		String des = "";
		String tmp = null;
		for (int i = 0; i < bts.length; i++) {
			tmp = (Integer.toHexString(bts[i] & 0xFF));
			if (tmp.length() == 1) {
				des += "0";
			}
			des += tmp;
		}
		return des;
	}


	/**
	 * 加密
	 *
	 * @param content  需要加密的内容
	 * @param password 加密密码
	 * @return
	 */
	public static String encryptPad(String content, String password) throws Exception {
		KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
		SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
		secureRandom.setSeed(password.getBytes());
		kgen.init(128, secureRandom);

		//kgen.init(128, new SecureRandom(password.getBytes()));
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		SecretKeySpec key = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPER_ALGORITHM);// 创建密码器
		byte[] byteContent = content.getBytes("utf-8");
		cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
		byte[] result = cipher.doFinal(byteContent);
		return parseByte2HexStr(result);
	}

	/**
	 * 加密
	 *
	 * @param content  需要加密的内容
	 * @param password 加密密码
	 * @return
	 */
	public static String encrypt(String content, String password) throws Exception {
//        KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
//        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
//        secureRandom.setSeed(password.getBytes());
//        kgen.init(128, secureRandom);
//        //kgen.init(128, new SecureRandom(password.getBytes()));
//        SecretKey secretKey = kgen.generateKey();
//        byte[] enCodeFormat = secretKey.getEncoded();
//        SecretKeySpec key = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);

		SecretKeySpec key = new SecretKeySpec(password.getBytes(), KEY_ALGORITHM);

		Cipher cipher = Cipher.getInstance(CIPER_ALGORITHM);// 创建密码器
		byte[] byteContent = content.getBytes("utf-8");
		cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
		byte[] result = cipher.doFinal(byteContent);
		return parseByte2HexStr(result);
	}
	
	/**
	 * 解密
	 *
	 * @param content  待解密内容
	 * @param password 解密密钥
	 * @return
	 */
	public static String decryptPad(String String, String password) throws Exception {
		byte[] content = parseHexStr2Byte(String);
		KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
		SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
		secureRandom.setSeed(password.getBytes());
		kgen.init(128, secureRandom);

		//kgen.init(128, new SecureRandom(password.getBytes()));
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		SecretKeySpec key = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPER_ALGORITHM);// 创建密码器
		cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
		byte[] result = cipher.doFinal(content);
		return new String(result);
	}

	/**
	 * 解密
	 *
	 * @param content  待解密内容
	 * @param password 解密密钥
	 * @return
	 */
	public static String decrypt(String String, String password) throws Exception {
		byte[] content = parseHexStr2Byte(String);

//        KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
//        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
//        secureRandom.setSeed(password.getBytes());
//        kgen.init(128, secureRandom);
//        //kgen.init(128, new SecureRandom(password.getBytes()));
//        SecretKey secretKey = kgen.generateKey();
//        byte[] enCodeFormat = secretKey.getEncoded();
//        SecretKeySpec key = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);

		SecretKeySpec key = new SecretKeySpec(password.getBytes(), KEY_ALGORITHM);


		Cipher cipher = Cipher.getInstance(CIPER_ALGORITHM);// 创建密码器
		cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
		byte[] result = cipher.doFinal(content);
		return new String(result);
	}

	public static String decryptaesKey(String string,String aesKey) throws Exception {
		return decrypt(string,aesKey);
	}

	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	public static void main(String[] args) throws Exception {
//		JSONObject jsonObj = new JSONObject();
//		jsonObj.put("uri", "/user/recharge/topup");
//		jsonObj.put("userId", "1");
//		String orginStr = jsonObj.toJSONString();
//		String afterEncrypt = encrypt(orginStr, CommonConstants.AES_KEY);
//		String afterDecrypt = decrypt(afterEncrypt, CommonConstants.AES_KEY);
//		System.out.println("orginStr : " + orginStr);
//		System.out.println("afterEncrypt : " + afterEncrypt);
//		System.out.println("afterDecrypt : " + afterDecrypt);
//
//		System.out.println(orginStr == afterDecrypt);
//		System.out.println(orginStr.equals(afterDecrypt));
//
//		LogUtils.debug(decrypt("E7C6EC40484EDE91AB737FD2FAB6430077334780F31E20083EA4154D46D0C7B0"));
	}
}
